﻿using System;
using System.Collections.Generic;
using System.Linq;
using Matrix.Common;
using System.ComponentModel;

namespace Matrix.ViewModel
{
   public class MatrixManager : IMatrixManagers
   {
      #region IMatrixManagers Members
      public MatrixManager()
      {
         Initialize();
      }

      private void Initialize()
      {
         firstMatrix.MatrixSizeChanged += new EventHandler(MatrixInstanceSizeChanged);
         secondMatrix.MatrixSizeChanged += new EventHandler(MatrixInstanceSizeChanged);
         AdditionOperation operation = new AdditionOperation(this);
         operations.Add(operation);
         SubtractOperation sub = new SubtractOperation(this);
         operations.Add(sub);
         MultiplyOperation mult = new MultiplyOperation(this);
         operations.Add(mult);

         resultsMatrix.IsEditable = false;

         selectedOperation = operations.First();
      }

      void MatrixInstanceSizeChanged(object sender, EventArgs e)
      {
         OnMatrixSizeChanged();
      }

      public void NextOperation()
      {
         int nextIndex = 0;
         var index = operations.IndexOf(selectedOperation);
         if (index != operations.Count - 1)
         {
            nextIndex = index + 1;
         }

         SelectedOperation = operations.ElementAt(nextIndex);
      }

      public void PreviousOperation()
      {
         int peviousIndex = operations.Count - 1;
         var index = operations.IndexOf(selectedOperation);
         if (index > 0)
         {
            peviousIndex = index - 1;
         }

         SelectedOperation = operations.ElementAt(peviousIndex);
      }

      private MatrixInstance firstMatrix = new MatrixInstance();
      public IMatrix FirstMatrix
      {
         get
         {
            return firstMatrix;
         }
      }

      private MatrixInstance secondMatrix = new MatrixInstance();
      public IMatrix SecondMatrix
      {
         get
         {
            return secondMatrix;
         }
      }

      private MatrixInstance resultsMatrix = new MatrixInstance();
      public IMatrix ResultMatrix
      {
         get
         {
            return resultsMatrix;
         }
      }

      private List<MatrixOperationBase> operations = new List<MatrixOperationBase>();
      public IEnumerable<IMatrixOperation> Operations
      {
         get
         {
            return operations;
         }
      }

      private MatrixOperationBase selectedOperation;
      public IMatrixOperation SelectedOperation
      {
         get
         {
            return selectedOperation;
         }
         set
         {
            selectedOperation = value as MatrixOperationBase;
            OnPropertyChanged("SelectedOperation");
         }
      }

      #endregion

      #region INotifyPropertyChanged Members

      public event PropertyChangedEventHandler PropertyChanged;

      private void OnPropertyChanged(string propertyName)
      {
         if (PropertyChanged != null)
         {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
         }
      }

      #endregion

      public event EventHandler MatrixSizeChanged;

      private void OnMatrixSizeChanged()
      {
         if (MatrixSizeChanged != null)
         {
            MatrixSizeChanged(this, null);
         }
      }
   }
}
